_ = require 'underscore'
request = require 'request'
zlib = require 'zlib'
async = require 'async'
debug = require('debug') 'rest'
logger = require('./logger') __filename

module.exports.request = (url, cbf) ->
  timeout = 60 * 1000
  if _.isObject url
    options = url
    options.timeout ?= timeout
  else
    options = 
      url : url
      timeout : timeout
      encoding : null
  options.headers = _.defaults options.headers || {}, {'Accept-Encoding' : 'gzip'}
  options.jar ?= true
  start = Date.now()
  request options, (err, res, body) =>
    statusCode = res?.statusCode
    if err
      debug "options: %j, error: %j", options, err
      cbf err
      requestLog options, start, 500, -1, err
    else if statusCode != 200
      err = new Error body
      err.code = statusCode
      cbf err
      requestLog options, start, statusCode, body.length, err
    else
      async.waterfall [
        (cbf) ->
          if res?.headers?['content-encoding'] == 'gzip'
            zlib.gunzip body, cbf
          else
            cbf null, body
        (data, cbf) ->
          debug "options: %j, data: %j", options, data
          if isJsonResponse res
            try
              data = JSON.parse data
            catch err
              cbf err
              return
            cbf null, data
      ], (err, data) ->
        requestLog options, start, statusCode, body.length, err
        cbf err, data
      

isJsonResponse = (res) ->
  contentType = res?.headers?['content-type']
  if !contentType
    false
  else if ~contentType.indexOf 'application/json'
    true
  else
    false

requestLog = (options, start, statusCode, length = 0, errContent) ->
  kb = 1024
  if length > kb
    length = Math.floor(length / kb) + 'kb'
  else
    length += 'b'
  type = options.method || 'GET'
  url = options.url
  logger.info "#{type} #{url} #{statusCode} #{Date.now() - start}ms - #{length}"
